package com;

import com.baomidou.mybatisplus.core.MybatisConfiguration;
import com.baomidou.mybatisplus.core.MybatisSqlSessionFactoryBuilder;
import com.baomidou.mybatisplus.core.batch.MybatisBatch;
import com.dao.UserDao;
import com.entity.User;
import com.mapper.UserMapper;
import com.ymx.darling.bean.entity.BeanInfo;
import com.ymx.darling.bean.entity.BeanInfoManager;
import com.ymx.darling.bean.entity.DefaultBeanInfoRepository;
import com.ymx.darling.bean.entity.FieldInfo;
import com.ymx.darling.bean.entity.id.IdType;
import com.ymx.darling.bean.sql.Statement;
import com.ymx.darling.build.Configuration;
import com.ymx.darling.build.DarlingConfig;
import com.ymx.darling.datasource.defaults.PooledDataSource;
import com.ymx.darling.dialect.DialectManager;
import com.ymx.darling.dialect.SQLiteDialect;
import com.ymx.darling.dialect.keygenerator.KeyGenerator;
import com.ymx.darling.executor.Executor;
import com.ymx.darling.expression.Expression;
import com.ymx.darling.log.Log;
import com.ymx.darling.log.nologging.NoLoggingImpl;
import com.ymx.darling.log.stdout.StdOutImpl;
import com.ymx.darling.session.Session;
import com.ymx.darling.session.SessionFactory;
import com.ymx.darling.session.defaults.DefaultSessionFactory;
import com.ymx.darling.session.setting.QuerySetting;
import com.ymx.darling.tenant.TenantManager;
import com.ymx.darling.util.ReflectUtil;
import com.ymx.darling.wrapper.QueryWrapper;
import com.ymx.darling.wrapper.UpdateWrapper;
import com.ymx.darling.wrapper.Wrappers;
import org.apache.ibatis.executor.BatchResult;
import org.apache.ibatis.mapping.Environment;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
import org.junit.Test;

import javax.sql.DataSource;
import java.io.File;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;

/**
 * @author 爱Java的小于
 */
public class Demo02 {
    private static final Integer COUNT = 5000;

    private static DataSource getDataSource() {
        PooledDataSource pooledDataSource = new PooledDataSource();
        pooledDataSource.setUrl("jdbc:sqlite:D:\\KFlanguage\\sqlite\\data\\mydatabase.db");
//        pooledDataSource.setUsername("root");
//        pooledDataSource.setPassword("root");
        pooledDataSource.setDriver("org.sqlite.JDBC");

        return pooledDataSource;
    }

    @Test
    public void test() {
        BeanInfoManager.registerBeanInfoRepository(new DefaultBeanInfoRepository());
        boolean logic = Expression.evalLogic("a.trim == '123'", " 123 ");
        System.out.println(logic);
    }


    @Test
    public void darlingTest() {
        DarlingConfig config = new DarlingConfig();
        config.setEntityPackage("com.entity");
        config.setMapperPackage("com.mapper");
        config.setLogImplClass(StdOutImpl.class);
        config.setDataSource(getDataSource());

        // 注册租户工厂
        TenantManager.setTenantFactory(() -> 1);

        SessionFactory sessionFactory = new DefaultSessionFactory(config);

        try (Session session = sessionFactory.openSession()) {
            UserMapper mapper = session.getMapper(UserMapper.class);
        }

    }


        /**
         * 生成200个顺序的User对象
         * 格式：用户1 男 1, 用户2 女 2, 用户3 男 3, ...
         */
        public static List<User> generateSequentialUsers() {
            List<User> userList = new ArrayList<>();

            for (int i = 1; i <= 30; i++) {
                User user = new User();

                // 使用set方法设置属性
                user.setUserName("用户" + i);
                user.setUserSex(i % 2 == 0 ? "女" : "男"); // 奇数男，偶子女
                user.setUserAge(i); // 年龄从1到200

                userList.add(user);
            }

            return userList;
        }

    private long test01(SessionFactory sessionFactory) {
        long start = System.currentTimeMillis();
        for (int i = 0; i < 1; i++) {
            try (Session session = sessionFactory.openSession()) {
                UserMapper mapper = session.getMapper(UserMapper.class);
                QueryWrapper wrapper = new QueryWrapper().eq(User::getUserAge, 32);
                User user = new User();
                user.setUserAge(32);
//                mapper.selectList(User.class, "select * from user where user_age = #{userAgeq} and user_political = #{userPolitical} and @{age2.sqlSegment}", user);
//                mapper.selectByAge(32);
            }
        }
        return System.currentTimeMillis() - start;
    }


    @Test
    public void test01() {
        // 创建mybatisplus的sessionFactory
        MybatisSqlSessionFactoryBuilder builder = new MybatisSqlSessionFactoryBuilder();
        MybatisConfiguration mybatisConfiguration = new MybatisConfiguration();
        mybatisConfiguration.addMapper(UserDao.class);
        Environment environment = new Environment("development", new JdbcTransactionFactory(), getDataSource());
        mybatisConfiguration.setEnvironment(environment);
//        mybatisConfiguration.setLogImpl(StdOutImpl.class);
        mybatisConfiguration.setMapUnderscoreToCamelCase(true);

        SqlSessionFactory sessionFactory = builder.build(mybatisConfiguration);

        List<User> users = generateSequentialUsers();

        MybatisBatch<User> mybatisBatch = new MybatisBatch<>(sessionFactory,  users, 1);
        MybatisBatch.Method<User> method = new MybatisBatch.Method<>(UserDao.class);

        List<BatchResult> execute = mybatisBatch.execute(method.insert());

        users.forEach(System.out::println);

//        try (SqlSession session = sessionFactory.openSession()) {
//            UserDao userDao = session.getMapper(UserDao.class);
//            int inserts = userDao.inserts(users);
//
//            users.forEach(System.out::println);
//
//            System.out.println(inserts);
//
//            session.commit();
//        }
    }

    private static class MyDialect extends SQLiteDialect {
        @Override
        public KeyGenerator getKeyGenerator() {
            return new MyKeyGenerator();
        }
    }


    private static class MyKeyGenerator implements KeyGenerator {
        @Override
        public void processBefore(List<Object> entityList, Statement statement) throws SQLException {
        }

        @Override
        public void processAfter(List<Object> entityList, Statement statement, PreparedStatement preparedStatement) throws SQLException {
            Executor executor = statement.getExecutor();
            Object entity = entityList.get(0);
            BeanInfo beanInfo = BeanInfoManager.getBeanInfo(entity.getClass());
            FieldInfo idColumnInfo = beanInfo.getIdColumnInfo();
            Statement generateKeyStatement = this.newGenerateKeyStatement(statement, "select last_insert_rowid()", idColumnInfo.getField().getType());

            List<Object> ids = executor.queryList(generateKeyStatement);
            try {
                ReflectUtil.setValue(idColumnInfo.getField(), entity, ids.get(0));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        @Override
        public IdType getIdType() {
            return IdType.AUTO;
        }
    }

    @Test
    public void test03() {
            printSortValue("afdf24fggf034fgrg_ 1 jukujk  g 9  4 325");
    }

    public static void printSortValue(String str) {
            if (str == null || str.isEmpty()) {
                return;
            }

        StringBuilder numberBuilder = new StringBuilder();
        Set<Integer> numberSet = new TreeSet<>();
        for (int i = 0, count = str.length(); i < count; i++) {
            char c = str.charAt(i);
            if (c >= '0' && c <= '9') {
                numberBuilder.append(c);
            } else {
                if (numberBuilder.length() > 0) {
                    numberSet.add(Integer.valueOf(numberBuilder.toString()));
                    numberBuilder = new StringBuilder();
                }
            }
        }
        // 处理首尾
        if (numberBuilder.length() > 0) {
            numberSet.add(Integer.valueOf(numberBuilder.toString()));
        }

        System.out.println(numberSet);
    }
}

interface A{

}
